package de.koller.oceanFramework.gl.util;

import de.koller.oceanFramework.gl.OceanGame;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.EXTTextureFilterAnisotropic;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class TextureUtil {
	
	public static int MAG_FILTER = GL11.GL_LINEAR;
	public static int MIN_FILTER = GL11.GL_LINEAR_MIPMAP_LINEAR;
	
	private TextureUtil() {}
	
	public static int makeAnisotropic( ParticleTexture texture ) {
		texture.flush();
		
		GL11.glEnable( GL11.GL_TEXTURE_2D );
		int id = GL11.glGenTextures();
		
		GL11.glBindTexture( GL11.GL_TEXTURE_2D, id );
		
		float mf = GL11.glGetFloat( EXTTextureFilterAnisotropic.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT );
		GL11.glTexParameterf( GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, mf );
		GL11.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR );
		GL11.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, MAG_FILTER );
		
		ByteBuffer buffer = ByteBuffer.allocateDirect( texture.getData().length );
		buffer.put( texture.getData() ).flip();
		
		GL11.glTexImage2D( GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, texture.getWidth(), texture.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer );
		OceanGame.checkForErrorGL( "Anisotropic" );
		
		return id;
	}
	
	public static int makeMipMap( ParticleTexture texture ) {
		texture.flush();
		texture.bind();
		
		int v = GL11.glGenTextures();
		ByteBuffer scratch = ByteBuffer.allocateDirect( texture.getWidth()*texture.getHeight()*4 );
		scratch.put( texture.getData() );
		scratch.flip();
		
		GL11.glBindTexture( GL11.GL_TEXTURE_2D, v );
		GL11.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, MAG_FILTER );
		GL11.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, MIN_FILTER );
		
		GLU.gluBuild2DMipmaps( GL11.GL_TEXTURE_2D, 4, texture.getWidth(), texture.getHeight(), GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, scratch );

		return v;
	}
	
	public static void bind( int texture ) {
		GL11.glEnable( GL11.GL_TEXTURE_2D );
		GL11.glBindTexture( GL11.GL_TEXTURE_2D, texture );
	}
	
	public static void delete( int texture ) {
		GL11.glDeleteTextures( texture );
	}
	
	public static ParticleTexture load( BufferedImage image, int ox, int oy, int ow, int oh ) {
		ParticleTexture p = ParticleTexture.generate( ow, oh );
		
		for( int x = ox; x < ox+ow; x++ )
			for( int y = oy; y < oy+oh; y++ )
				p.setPixel( image.getRGB( x, y ), x-ox, y-oy );
		
		p.flush();
		return p;
	}
	
	public static BufferedImage loadImage( String file ) {
		ClassLoader cl = TextureUtil.class.getClassLoader();
		InputStream in = cl.getResourceAsStream( file );
		BufferedImage bi = null;
		
		try {
			bi = ImageIO.read( in );
		} catch( IOException ex ) {
			System.err.println( "can't find: " + file );
			bi = new BufferedImage( 32, 32, BufferedImage.TYPE_INT_ARGB );
		}
		
		return bi;
	}
	
	public static RasterManager load( String file ) {
		BufferedImage bi = loadImage( file );	
		RasterManager p = new RasterManager( bi.getWidth(), bi.getHeight() );
		
		for( int x = 0; x < bi.getWidth(); x++ )
			for( int y = 0; y < bi.getHeight(); y++ )
				p.setPixel( bi.getRGB( x, y ), x, y );
		
		return p;
	}
	
	public static ParticleTexture loadTexture( String file ) {
		RasterManager rm = load( file );
		ParticleTexture t = ParticleTexture.generate( rm.getWidth(), rm.getHeight() );
		
		for( int x = 0; x < rm.getWidth(); x++ )
			for( int y = 0; y < rm.getHeight(); y++ )
				t.setPixel( rm.colorAt( x, y ), x, y );
		t.flush();
				
		return t;
	}
	
}
